/*
 * Copyright 2002-2020 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.beans.factory.support;

import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import org.springframework.beans.factory.BeanCreationException;
import org.springframework.beans.factory.BeanCreationNotAllowedException;
import org.springframework.beans.factory.BeanCurrentlyInCreationException;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.config.SingletonBeanRegistry;
import org.springframework.core.SimpleAliasRegistry;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;

/**
 *
 * 共享bean实例的注册表，实现了SingletonBeanRegistry接口。允许注册应该被注册表的所有调用者共享的单例bean对象，通过bean的名字进行获取。
 *
 * 这个类也支持注册DisposableBean实例，（对不对应注册的单实例bean都行），在注册表关闭的时候销毁。
 * 可以注册bean实例之间的依赖关系以强制执行适当的关闭顺序。
 * 这个类主要是作为beanFactory实现的基类，分解出单实例bean的共公共管理功能模块。
 * ConfigurableBeanFactory接口扩展了SingletonBeanRegistry接口。
 *
 * 相比于AbstractBeanFactory 和 DefaultListableBeanFactory ，该类不假定 bean的定义概念，也不提前预设bean实例的创建过程，可以作为嵌套的助手来委托。
 * @author Juergen Hoeller
 * @since 2.0
 * @see #registerSingleton
 * @see #registerDisposableBean
 * @see org.springframework.beans.factory.DisposableBean
 * @see org.springframework.beans.factory.config.ConfigurableBeanFactory
 */
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {

	/** 要保留的最大忽略异常数 */
	private static final int SUPPRESSED_EXCEPTIONS_LIMIT = 100;

	/*一级缓存  k ：beanName  v:beanName对应的单实例对象引用  */
	private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
	/*三级缓存 k：beanName v：单实例bean的工厂*/
	private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
	/*二级缓存：早期暴露的bean实例  k：beanName  v:实例化但是还没有初始化的bean对象*/
	private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>(16);

	/** 支持排序的单实例注册表 */
	private final Set<String> registeredSingletons = new LinkedHashSet<>(256);

	/** 当前正在创建中的bean对象 */
	private final Set<String> singletonsCurrentlyInCreation =
			Collections.newSetFromMap(new ConcurrentHashMap<>(16));

	/** 忽略创建检查的bean名称 */
	private final Set<String> inCreationCheckExclusions =
			Collections.newSetFromMap(new ConcurrentHashMap<>(16));

	/** 存放异常出现的相关原因的集合*/
	@Nullable
	private Set<Exception> suppressedExceptions;

	/** 标志，指示我们目前是否在销毁单实例bean中*/
	private boolean singletonsCurrentlyInDestruction = false;

	/** 存放一次性bean的缓存*/
	private final Map<String, Object> disposableBeans = new LinkedHashMap<>();

	/** 包含 bean 名称之间的映射：bean 名称到 bean 包含的 bean 名称集。 */
	private final Map<String, Set<String>> containedBeanMap = new ConcurrentHashMap<>(16);

	/** k：beanName、 v：依赖他的所有bean。*/
	private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<>(64);

	/** k：beanName ，v:这个bean依赖的所有bean。 */
	private final Map<String, Set<String>> dependenciesForBeanMap = new ConcurrentHashMap<>(64);


	@Override
	public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException {
		Assert.notNull(beanName, "Bean name must not be null");
		Assert.notNull(singletonObject, "Singleton object must not be null");
		synchronized (this.singletonObjects) {
			Object oldObject = this.singletonObjects.get(beanName);
			if (oldObject != null) {
				throw new IllegalStateException("Could not register object [" + singletonObject +
						"] under bean name '" + beanName + "': there is already object [" + oldObject + "] bound");
			}
			addSingleton(beanName, singletonObject);
		}
	}

	/**
	 * Add the given singleton object to the singleton cache of this factory.
	 * <p>To be called for eager registration of singletons.
	 * @param beanName the name of the bean
	 * @param singletonObject the singleton object
	 */
	protected void addSingleton(String beanName, Object singletonObject) {
		synchronized (this.singletonObjects) {
			/*放到一级缓存*/
			this.singletonObjects.put(beanName, singletonObject);
			/*清理三级缓存*/
			this.singletonFactories.remove(beanName);
			/*清理二级缓存*/
			this.earlySingletonObjects.remove(beanName);
			/*注册到创建成功的单实例bean集合*/
			this.registeredSingletons.add(beanName);
		}
	}

	/**
	 * Add the given singleton factory for building the specified singleton
	 * if necessary.
	 * <p>To be called for eager registration of singletons, e.g. to be able to
	 * resolve circular references.
	 * @param beanName the name of the bean
	 * @param singletonFactory the factory for the singleton object
	 */
	protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
		Assert.notNull(singletonFactory, "Singleton factory must not be null");
		synchronized (this.singletonObjects) {
			if (!this.singletonObjects.containsKey(beanName)) {
				/*加入到三级缓存*/
				this.singletonFactories.put(beanName, singletonFactory);
				/*从二级缓存删除*/
				this.earlySingletonObjects.remove(beanName);
				/*添加到单实例bean的注册表*/
				this.registeredSingletons.add(beanName);
			}
		}
	}

	@Override
	@Nullable
	public Object getSingleton(String beanName) {
		/*方法重载   allowEarlyReference  是否允许拿到早期引用*/
		return getSingleton(beanName, true);
	}

	/**
	 * 返回在给定名称下注册的（原始）单例对象。
	 * 检查已经实例化的单例，并允许早期引用当前创建的单例（解决循环引用）。
	 */
	@Nullable
	protected Object getSingleton(String beanName, boolean allowEarlyReference) {
		/*通过名字去一级缓存拿单实例bean对象*/
		Object singletonObject = this.singletonObjects.get(beanName);
		/*如果拿到的对象实例是null，有几种情况？
		* 1.单实例确实没创建呢
		* 2. 当前正在创建中，发生了循环依赖了，这个时候实例其实在二级缓存
		*
		* 循环依赖：
		* A->B  B->A
		* 单实例的循环依赖有几种？
		* 1.构造方法   无解
		* 2.setter    有解   通过三级缓存
		*
		* 三级缓存实际上如何解决的循环依赖？
		* 利用bean的中间状态 ：已经实例化但是还未初始化
		* A-B  B->A  setter依赖
		* 1. 假设spring先实例化A，首先拿到A的构造方法，反射创建A的早期实例对象，这个早期对象被包装了一下，
		* 变成ObjectFactory对象，放到三级缓存。
		* 2. 处理A的依赖数据，检查发现 A依赖B ，所以，spring 根据 B的类型去容器中去getBean(B.class) ,这里就是递归了
		* 3. 首先拿到B的构造方法，反射创建B的早期实例对象，把B包装成ObjectFactory对象，放到三级缓存。
		* 4. 处理Bde 依赖数据，检查发现，B依赖对象A，所以接下来，spring就会根据A类型去容器去getBean(A.class) 对象，这个时候又递归了
		* 5. 程序还会走到当前方法getSingleton
		* 6. 条件一成立，条件二成立。
		*
		*/
		if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
			/*从二级缓存拿数据*/
			singletonObject = this.earlySingletonObjects.get(beanName);
			/*条件成立说明二级缓存没有  去三级缓存拿*/
			if (singletonObject == null && allowEarlyReference) {
				synchronized (this.singletonObjects) {
					/*
					* spring为什么需要有三级缓存，而不是只有二级缓存？
					* AOP 靠什么实现呢？动态代理  jdk cglib
					* 代理：静态代理：需要手动写代码实现新的JAVA文件，这个JAV类需要和代理对象实现同一个接口，内部维护一个被代理对象
					* 	代理类在接口调用原生对象前后可以加一些逻辑。
					* 	代理对象和被代理对象是两个不同的内存地址，一定是不一样的
					* 	   动态代理：... 不需要人为写代码了，而是依靠字节码框架动态生成字节码文件，然后jvm在进行加载，然后也是一样
					* 	也是去new代理对象，这个代理对象没啥特殊的，也是内部保留了原生对象，然后再调用原生对象前后实现的字节码增强。
					* 两者共同点：代理对象和被代理对象实际上都不是同一内存地址
					*
					* 三级缓存在这里有什么意义呢？
					* 三级缓存里面保存的是对象工厂，这个对象工厂内部保留着原生对象的引用，ObjectFactory的实现类，getObject方法，
					* 需要考虑一个问题：到底是返回原生的，还是增强的？
					* getObject会判断当前早期实例是否需要被增强，如果是 那么提前完成动态代理增强，返回代理对象，否则，返回原生对象。
					*
					*/
					/*从一级缓存拿*/
					singletonObject = this.singletonObjects.get(beanName);
					if (singletonObject == null) {
						/*从二级缓存拿*/
						singletonObject = this.earlySingletonObjects.get(beanName);

						if (singletonObject == null) {
							/*从三级缓存拿*/
							ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
							/*条件成立：说明第三级缓存有数据。这里就涉及到了缓存的升级 ，很简单 ，从三级挪到二级 ，再反手干掉三级的。*/
							if (singletonFactory != null) {
								singletonObject = singletonFactory.getObject();
								this.earlySingletonObjects.put(beanName, singletonObject);
								this.singletonFactories.remove(beanName);
							}
						}
					}
				}
			}
		}
		return singletonObject;
	}

	public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
		Assert.notNull(beanName, "Bean name must not be null");
		synchronized (this.singletonObjects) {
			/*从一级缓存拿bean实例*/
			Object singletonObject = this.singletonObjects.get(beanName);
			/*bean对象实例为空*/
			if (singletonObject == null) {
				/*容器销毁会设置这个属性为true，这个时候不能创建bean'实例了，会报错！*/
				if (this.singletonsCurrentlyInDestruction) {
					throw new BeanCreationNotAllowedException(beanName,
							"Singleton bean creation not allowed while singletons of this factory are in destruction " +
							"(Do not request a bean from a BeanFactory in a destroy method implementation!)");
				}
				if (logger.isDebugEnabled()) {
					logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
				}
				/*
				* 将当前beanName放在正在创建中的单实例集合，放入成功，说明没有产生循环依赖，失败则说明产生循环依赖，里面会抛出异常。
				* 举个例子，构造方法参数依赖：
				*  a b   b  a
				* 1.加载a，根据a的构造方法，想要去实例化a对象，但是发现a的构造方法有一个参数是b，在这之前已经向这个集合添加了a
				* 2.因为a的构造方法依赖b，所以出发了加载b的逻辑
				* 3.加载b,根据b  的构造方法，想要去实例化 b 对象 ，但是发现 b 的构造方法有一个参数是 a ，在这之前，已经向这个集合中添加了 a b
				* 4.因为 b 的构造方法依赖 a ， 所以再次触发了加载a的逻辑
				* 5.再次来到这个getSingleton()，调用beforeSingletonCreation(A) ,因为创建中 集合 已经有A了，所以添加失败 ，抛出异常。
				*/
				beforeSingletonCreation(beanName);
				boolean newSingleton = false;
				boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
				if (recordSuppressedExceptions) {
					this.suppressedExceptions = new LinkedHashSet<>();
				}
				try {
					singletonObject = singletonFactory.getObject();
					newSingleton = true;
				}
				catch (IllegalStateException ex) {
					// Has the singleton object implicitly appeared in the meantime ->
					// if yes, proceed with it since the exception indicates that state.
					singletonObject = this.singletonObjects.get(beanName);
					if (singletonObject == null) {
						throw ex;
					}
				}
				catch (BeanCreationException ex) {
					if (recordSuppressedExceptions) {
						for (Exception suppressedException : this.suppressedExceptions) {
							ex.addRelatedCause(suppressedException);
						}
					}
					throw ex;
				}
				finally {
					/*走到这里   bean创建完了  将当前beanName 从创建中集合中拿出去*/
					if (recordSuppressedExceptions) {
						this.suppressedExceptions = null;
					}
					/*单实例创建后逻辑   默认将单实例bean标记为不在创建*/
					afterSingletonCreation(beanName);
				}
				/*判断如果是创建了一个新的实例*/
				if (newSingleton) {
					/*加入到一级缓存中*/
					addSingleton(beanName, singletonObject);
				}
			}
			return singletonObject;
		}
	}

	/**
	 * Register an exception that happened to get suppressed during the creation of a
	 * singleton bean instance, e.g. a temporary circular reference resolution problem.
	 * <p>The default implementation preserves any given exception in this registry's
	 * collection of suppressed exceptions, up to a limit of 100 exceptions, adding
	 * them as related causes to an eventual top-level {@link BeanCreationException}.
	 * @param ex the Exception to register
	 * @see BeanCreationException#getRelatedCauses()
	 */
	protected void onSuppressedException(Exception ex) {
		synchronized (this.singletonObjects) {
			if (this.suppressedExceptions != null && this.suppressedExceptions.size() < SUPPRESSED_EXCEPTIONS_LIMIT) {
				this.suppressedExceptions.add(ex);
			}
		}
	}

	/**
	 * Remove the bean with the given name from the singleton cache of this factory,
	 * to be able to clean up eager registration of a singleton if creation failed.
	 * @param beanName the name of the bean
	 * @see #getSingletonMutex()
	 */
	protected void removeSingleton(String beanName) {
		synchronized (this.singletonObjects) {
			this.singletonObjects.remove(beanName);
			this.singletonFactories.remove(beanName);
			this.earlySingletonObjects.remove(beanName);
			this.registeredSingletons.remove(beanName);
		}
	}

	@Override
	public boolean containsSingleton(String beanName) {
		return this.singletonObjects.containsKey(beanName);
	}

	@Override
	public String[] getSingletonNames() {
		synchronized (this.singletonObjects) {
			return StringUtils.toStringArray(this.registeredSingletons);
		}
	}

	@Override
	public int getSingletonCount() {
		synchronized (this.singletonObjects) {
			return this.registeredSingletons.size();
		}
	}


	public void setCurrentlyInCreation(String beanName, boolean inCreation) {
		Assert.notNull(beanName, "Bean name must not be null");
		if (!inCreation) {
			this.inCreationCheckExclusions.add(beanName);
		}
		else {
			this.inCreationCheckExclusions.remove(beanName);
		}
	}

	public boolean isCurrentlyInCreation(String beanName) {
		Assert.notNull(beanName, "Bean name must not be null");
		return (!this.inCreationCheckExclusions.contains(beanName) && isActuallyInCreation(beanName));
	}

	protected boolean isActuallyInCreation(String beanName) {
		return isSingletonCurrentlyInCreation(beanName);
	}

	/**
	 * Return whether the specified singleton bean is currently in creation
	 * (within the entire factory).
	 * @param beanName the name of the bean
	 */
	public boolean isSingletonCurrentlyInCreation(String beanName) {
		return this.singletonsCurrentlyInCreation.contains(beanName);
	}

	/**
	 * Callback before singleton creation.
	 * <p>The default implementation register the singleton as currently in creation.
	 * @param beanName the name of the singleton about to be created
	 * @see #isSingletonCurrentlyInCreation
	 */
	protected void beforeSingletonCreation(String beanName) {
		if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
			throw new BeanCurrentlyInCreationException(beanName);
		}
	}

	/**
	 * Callback after singleton creation.
	 * <p>The default implementation marks the singleton as not in creation anymore.
	 * @param beanName the name of the singleton that has been created
	 * @see #isSingletonCurrentlyInCreation
	 */
	protected void afterSingletonCreation(String beanName) {
		if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) {
			throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation");
		}
	}


	/**
	 * Add the given bean to the list of disposable beans in this registry.
	 * <p>Disposable beans usually correspond to registered singletons,
	 * matching the bean name but potentially being a different instance
	 * (for example, a DisposableBean adapter for a singleton that does not
	 * naturally implement Spring's DisposableBean interface).
	 * @param beanName the name of the bean
	 * @param bean the bean instance
	 */
	public void registerDisposableBean(String beanName, DisposableBean bean) {
		synchronized (this.disposableBeans) {
			this.disposableBeans.put(beanName, bean);
		}
	}

	/**
	 * Register a containment relationship between two beans,
	 * e.g. between an inner bean and its containing outer bean.
	 * <p>Also registers the containing bean as dependent on the contained bean
	 * in terms of destruction order.
	 * @param containedBeanName the name of the contained (inner) bean
	 * @param containingBeanName the name of the containing (outer) bean
	 * @see #registerDependentBean
	 */
	public void registerContainedBean(String containedBeanName, String containingBeanName) {
		synchronized (this.containedBeanMap) {
			Set<String> containedBeans =
					this.containedBeanMap.computeIfAbsent(containingBeanName, k -> new LinkedHashSet<>(8));
			if (!containedBeans.add(containedBeanName)) {
				return;
			}
		}
		registerDependentBean(containedBeanName, containingBeanName);
	}

	/**
	 * 为给定的 bean 注册一个依赖 bean，在给定的 bean 被销毁之前被销毁。
	 * @param beanName the name of the bean
	 * @param dependentBeanName the name of the dependent bean
	 */
	public void registerDependentBean(String beanName, String dependentBeanName) {
		/*处理别名*/
		String canonicalName = canonicalName(beanName);

		synchronized (this.dependentBeanMap) {
			/*
			* a b
			* 记录谁依赖了b
			* */
			Set<String> dependentBeans =
					this.dependentBeanMap.computeIfAbsent(canonicalName, k -> new LinkedHashSet<>(8));
			if (!dependentBeans.add(dependentBeanName)) {
				return;
			}
		}
		/*
		* a  b
		*
		* 记录 a 依赖了谁
		* */
		synchronized (this.dependenciesForBeanMap) {
			Set<String> dependenciesForBean =
					this.dependenciesForBeanMap.computeIfAbsent(dependentBeanName, k -> new LinkedHashSet<>(8));
			dependenciesForBean.add(canonicalName);
		}
	}

	/**
	 * 给定指定的依赖 bean 是否已注册为依赖于给定的 bean 或其任何传递依赖项。
	 * @param beanName the name of the bean to check
	 * @param dependentBeanName the name of the dependent bean
	 * @since 4.0
	 */
	protected boolean isDependent(String beanName, String dependentBeanName) {
		synchronized (this.dependentBeanMap) {
			return isDependent(beanName, dependentBeanName, null);
		}
	}
	/**
	 * 假设发生了循环依赖
	 *
	 * a b  互相依赖
	 * 以b的视角 dependentBeanMap {"B":{"A"}}
	 * 以a为视角 dependenciesForBeanMap {"A":{"B"}}
	 * beanName:B    dependentBeanName:A
	 */
	private boolean isDependent(String beanName, String dependentBeanName, @Nullable Set<String> alreadySeen) {
		if (alreadySeen != null && alreadySeen.contains(beanName)) {
			return false;
		}
		String canonicalName = canonicalName(beanName);
		Set<String> dependentBeans = this.dependentBeanMap.get(canonicalName);
		if (dependentBeans == null) {
			return false;
		}
		/*
		* {"A"} 包含a 条件成立  返回true
		* */
		if (dependentBeans.contains(dependentBeanName)) {
			return true;
		}
		/*
		* 这里是判断多个标签形成环时候的处理逻辑
		* */
		for (String transitiveDependency : dependentBeans) {
			if (alreadySeen == null) {
				alreadySeen = new HashSet<>();
			}
			alreadySeen.add(beanName);
			if (isDependent(transitiveDependency, dependentBeanName, alreadySeen)) {
				return true;
			}
		}
		return false;
	}

	/**
	 * Determine whether a dependent bean has been registered for the given name.
	 * @param beanName the name of the bean to check
	 */
	protected boolean hasDependentBean(String beanName) {
		return this.dependentBeanMap.containsKey(beanName);
	}

	/**
	 * Return the names of all beans which depend on the specified bean, if any.
	 * @param beanName the name of the bean
	 * @return the array of dependent bean names, or an empty array if none
	 */
	public String[] getDependentBeans(String beanName) {
		Set<String> dependentBeans = this.dependentBeanMap.get(beanName);
		if (dependentBeans == null) {
			return new String[0];
		}
		synchronized (this.dependentBeanMap) {
			return StringUtils.toStringArray(dependentBeans);
		}
	}

	/**
	 * Return the names of all beans that the specified bean depends on, if any.
	 * @param beanName the name of the bean
	 * @return the array of names of beans which the bean depends on,
	 * or an empty array if none
	 */
	public String[] getDependenciesForBean(String beanName) {
		Set<String> dependenciesForBean = this.dependenciesForBeanMap.get(beanName);
		if (dependenciesForBean == null) {
			return new String[0];
		}
		synchronized (this.dependenciesForBeanMap) {
			return StringUtils.toStringArray(dependenciesForBean);
		}
	}

	public void destroySingletons() {
		if (logger.isTraceEnabled()) {
			logger.trace("Destroying singletons in " + this);
		}
		synchronized (this.singletonObjects) {
			/*设置该属性，表示当前beanFactory处于销毁状态*/
			this.singletonsCurrentlyInDestruction = true;
		}

		String[] disposableBeanNames;
		/*disposable ？ 创建单实例时，会检查当前单实例bean类型是否实现了DisposableBean接口，
		* 如果实现了该接口，对应容器销毁的时候，需要执行该bean.destroy()*/
		synchronized (this.disposableBeans) {
			disposableBeanNames = StringUtils.toStringArray(this.disposableBeans.keySet());
		}
		/*对应上面的bean的销毁逻辑*/
		for (int i = disposableBeanNames.length - 1; i >= 0; i--) {
			/*step into 具体的销毁逻辑*/
			destroySingleton(disposableBeanNames[i]);
		}
		/*清空缓存*/
		this.containedBeanMap.clear();
		this.dependentBeanMap.clear();
		this.dependenciesForBeanMap.clear();
		/*清理单实例bean的缓存*/
		clearSingletonCache();
	}

	/**
	 * Clear all cached singleton instances in this registry.
	 * @since 4.3.15
	 */
	protected void clearSingletonCache() {
		synchronized (this.singletonObjects) {
			this.singletonObjects.clear();
			this.singletonFactories.clear();
			this.earlySingletonObjects.clear();
			this.registeredSingletons.clear();
			this.singletonsCurrentlyInDestruction = false;
		}
	}

	/**
	 * Destroy the given bean. Delegates to {@code destroyBean}
	 * if a corresponding disposable bean instance is found.
	 * @param beanName the name of the bean
	 * @see #destroyBean
	 */
	public void destroySingleton(String beanName) {
		/*清理三级缓存*/
		removeSingleton(beanName);

		// Destroy the corresponding DisposableBean instance.
		DisposableBean disposableBean;
		synchronized (this.disposableBeans) {
			/*注册时候会向disposableBeans 内部存放 实现了 DisposableBean 接口的 bean*/
			disposableBean = (DisposableBean) this.disposableBeans.remove(beanName);
		}
		/*销毁bean 的逻辑*/
		destroyBean(beanName, disposableBean);
	}

	/**
	 * Destroy the given bean. Must destroy beans that depend on the given
	 * bean before the bean itself. Should not throw any exceptions.
	 * @param beanName the name of the bean
	 * @param bean the bean instance to destroy
	 */
	protected void destroyBean(String beanName, @Nullable DisposableBean bean) {
		// Trigger destruction of dependent beans first...
		Set<String> dependencies;
		/*移除当前bean 的依赖信息  dependentBeanMap？保存依赖当前bean 的其他bean 的信息*/
		synchronized (this.dependentBeanMap) {
			// Within full synchronization in order to guarantee a disconnected Set
			dependencies = this.dependentBeanMap.remove(beanName);
		}
		if (dependencies != null) {
			if (logger.isTraceEnabled()) {
				logger.trace("Retrieved dependent beans for bean '" + beanName + "': " + dependencies);
			}
			for (String dependentBeanName : dependencies) {
				/*因为被依赖bean要被回收了，所以如果有bean依赖当前bean 迭代销毁*/
				destroySingleton(dependentBeanName);
			}
		}
		/*上面处理完了这个bean实例的依赖bean，现在开始销毁她自己*/
		// Actually destroy the bean now...
		if (bean != null) {
			try {
				/*调用bean 的销毁方法*/
				bean.destroy();
			}
			catch (Throwable ex) {
				if (logger.isWarnEnabled()) {
					logger.warn("Destruction of bean with name '" + beanName + "' threw an exception", ex);
				}
			}
		}

		// Trigger destruction of contained beans...
		/*触发当前bean所依赖的bean的依赖关系移除逻辑，这个依赖关系是保存在一个map容器的，需要清理map容器。再根据map容器的依赖关系清理相关的bean对象 */
		Set<String> containedBeans;
		synchronized (this.containedBeanMap) {
			// Within full synchronization in order to guarantee a disconnected Set
			containedBeans = this.containedBeanMap.remove(beanName);
		}
		if (containedBeans != null) {
			for (String containedBeanName : containedBeans) {
				destroySingleton(containedBeanName);
			}
		}

		// 从其他bean的依赖项中移除已销毁的bean。
		synchronized (this.dependentBeanMap) {
			for (Iterator<Map.Entry<String, Set<String>>> it = this.dependentBeanMap.entrySet().iterator(); it.hasNext();) {
				Map.Entry<String, Set<String>> entry = it.next();
				Set<String> dependenciesToClean = entry.getValue();
				dependenciesToClean.remove(beanName);
				if (dependenciesToClean.isEmpty()) {
					it.remove();
				}
			}
		}

		// 移除被销毁的bean的准备好的依赖关系信息。 dependenciesForBeanMap：保存当前bean都依赖了谁
		this.dependenciesForBeanMap.remove(beanName);
	}

	/**
	 * Exposes the singleton mutex to subclasses and external collaborators.
	 * <p>Subclasses should synchronize on the given Object if they perform
	 * any sort of extended singleton creation phase. In particular, subclasses
	 * should <i>not</i> have their own mutexes involved in singleton creation,
	 * to avoid the potential for deadlocks in lazy-init situations.
	 */
	@Override
	public final Object getSingletonMutex() {
		return this.singletonObjects;
	}

}
